package com.healthcarex.hip.saas.message.processor;

import java.io.*;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import com.healthcarex.hip.saas.common.util.xml.XmlHelper;
import com.healthcarex.hip.saas.message.core.AbstractMessage;
import com.healthcarex.hip.saas.message.core.MessageModel;
import com.healthcarex.hip.saas.message.schema.MessageSchemaDefinition;
import lombok.extern.slf4j.Slf4j;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

@Slf4j
public abstract class AbstractMessageProcessor implements IMessageProcessor {

    @Override
    public abstract AbstractMessage generate(MessageModel paramMessageModel,
                                             MessageSchemaDefinition paramMessageSchemaDefinition);

    @Override
    public abstract String getMessageType();

    @Override
    public abstract MessageModel parse(AbstractMessage paramAbstractMessage) throws Exception;

    protected abstract boolean verify(Object paramObject, MessageSchemaDefinition paramMessageSchemaDefinition);

    protected Document stringToDocument(String message)
            throws SAXException, IOException, ParserConfigurationException {
        Document doc;
        if ((message == null) || ("".equalsIgnoreCase(message.trim()))) {
            return null;
        }
        try {
            doc = messageToDocument(message);
        } catch (SAXException e) {
            log.warn("Xml解析失败！！！");
            String t = XmlHelper.removeInvalidCharRefs(message);
            doc = messageToDocument(t);
        }
        return doc;
    }

    public static String getStackTrace(Throwable e) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        e.printStackTrace(pw);
        pw.close();
        return sw.toString();
    }

    protected Document messageToDocument(String message)
            throws ParserConfigurationException, SAXException, IOException {
        StringReader sr = new StringReader(message);
        InputSource is = new InputSource(sr);
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

        factory.setNamespaceAware(true);
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document doc = builder.parse(is);

        return doc;
    }

    protected String documentToString(Document doc)
            throws TransformerException {
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer transformer = tf.newTransformer();
        transformer.setOutputProperty("encoding", "utf-8");
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        transformer.transform(new DOMSource(doc), new StreamResult(bos));
        String xmlStr = bos.toString();

        return xmlStr;
    }
}
